#ifndef LDM_HPP
#define LDM_HPP

#include<unordered_map>
#include<string>
#include<vector>
#include<exception>

using record = std::unordered_map<std::string,std::string>;

class ldmError:public std::exception{
	std::string ev;
public:
	ldmError(const std::string &val="ldmError"):ev(val){}
	const char *what(){
		return ev.c_str();
	}
};

class ldm{
	std::unordered_map<std::string,record> data;
public:
	ldm(){
		
	}
	ldm(const ldm &from){
		this->data=from.data;
	}
	bool exist(const std::string &key) const {
		return data.find(key)!=data.end();
	}
	record search(const std::string &key) const {
		if(exist(key)){
			return data.find(key)->second;
		}
		throw ldmError("a unknown key");
	}
	void insert(const std::string &key,const record &val){
		if(exist(key)){
			throw ldmError("a duplicate key");
		}
		data[key]=val;
	}
	void update(const std::string &key,const record &chance){
		if(!exist(key)){
			throw ldmError("a unknown key");
		}
		for(auto &ec:chance){
			data[key][ec.first]=ec.second;
		}
	}
	void remove(const std::string &key){
		if(exist(key)){
			data.erase(key);
		}
		throw ldmError("a unknown key");
	}
	bool get(const std::string &key,const record &val) const {
		if(exist(key)){
			return data.find(key) ->second == val;
		}
		return false;
	}
	std::vector<std::string> keys() const {
		std::vector<std::string> ret;
		for(const auto &ec:data){
			ret.push_back(ec.first);
		}
		return ret;
	}
	void clear(){
		data.clear();
	}
};

#endif